package com.azt.provider.impl;

import com.azt.api.dto.CartListData;
import com.azt.api.dto.CartProduct;
import com.azt.api.dto.ProductData;
import com.azt.api.dto.hot.ProHotFloorExt;
import com.azt.api.dto.hot.ProShopFloorExt;
import com.azt.api.dto.hot.ProShopHotExt;
import com.azt.api.dto.item.ProSkuExt;
import com.azt.api.dto.item.ProductExt;
import com.azt.api.dto.item.SkuModel;
import com.azt.api.dto.shop.ProCategory;
import com.azt.api.dto.shop.ProSearchParam;
import com.azt.api.enums.ProStockOperateType;
import com.azt.api.enums.ProStockType;
import com.azt.api.enums.ProductStateEnum;
import com.azt.api.pojo.*;
import com.azt.api.service.*;
import com.azt.exception.BaseException;
import com.azt.model.page.TPagination;
import com.azt.provider.mapper.*;
import com.azt.utils.PasswordUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xiaoleilu.hutool.convert.Convert;
import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

@Service
@Transactional
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ProCategoryService proCategoryService;

    @Autowired
    private ProductStockMapper productStockMapper;

    @Autowired
    private ProSkuMapper proSkuMapper;

    @Autowired
    private ProSkuAttrMapper proSkuAttrMapper;

    @Autowired
    private MemberService memberService;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private CompanySignService companySignService;

    @Autowired
    private ProHotFloorMapper proHotFloorMapper;

    @Autowired
    private ProShopFloorMapper proShopFloorMapper;

    @Autowired
    private ProShopHotProductMapper proShopHotProductMapper;

    @Autowired
    private ProRepositoryMapper proRepositoryMapper;

    @Autowired
    private MsgConfigService msgConfigService;

    @Override
    public void updateProductSelective(Product product) {
        productMapper.updateByPrimaryKeySelective(product);
    }

    @Override
    public void updateProduct(Product product) {
        productMapper.updateByPrimaryKey(product);
    }

    @Override
    public void updateCenPrice(int skuId, double cenPrice) {
        ProSku proSku = new ProSku();
        proSku.setId(skuId);
        proSku.setCenPrice(cenPrice);
        proSkuMapper.updateByPrimaryKeySelective(proSku);
    }

    @Override
    public void updateHotPrice(int skuId, double hotPrice) {
        ProSku proSku = new ProSku();
        proSku.setId(skuId);
        proSku.setHotPrice(hotPrice);
        proSkuMapper.updateByPrimaryKeySelective(proSku);
    }

    @Override
    public void insertProductStockSelective(ProductStock productStock) {
        productStockMapper.insertSelective(productStock);
    }

    @Override
    public void updateProSkuSelective(ProSku proSku) {
        proSkuMapper.updateByPrimaryKeySelective(proSku);
    }

    @Override
    public Double calcProductPrice(boolean isSigned, boolean isCenMember, boolean isHotProduct, Double memberPrice, Double hotPrice, Double cenPrice) {
        if(isSigned && isCenMember && cenPrice != null && cenPrice.doubleValue() > 0) {
            return cenPrice;
        } else if(isHotProduct && hotPrice != null && hotPrice.doubleValue() > 0) {
            return hotPrice;
        } else {
            return memberPrice;
        }
    }

    @Override
    public Double calcProductPrice(int skuId, int buyerId) {
        Double realPrice = null;
        ProSku proSku = getProSkuById(skuId);
        if(proSku != null) {
            Product product = getProductById(proSku.getProductId());
            if(product != null) {
                boolean isSigned = companySignService.getCompanySign(buyerId, 2, true) != null;
                boolean isCenMember = memberService.getCenMember(product.getCustomerId()) != null;
                boolean isHotProduct = this.isHotProduct(proSku.getProductId());
                realPrice = calcProductPrice(isSigned, isCenMember, isHotProduct, proSku.getMemberPrice(), proSku.getHotPrice(), proSku.getCenPrice());
            }
        }
        return realPrice;
    }

    @Override
    public boolean isHotProduct(int productId) {
        return productMapper.isHotProduct(productId);
    }

    @Override
    public List<Map> searchProduct(Map param) {
        return productMapper.searchProduct(param);
    }

    @Override
    public Product getProductById(int productId) {
        return productMapper.selectByPrimaryKey(productId);
    }

    @Override
    public List<CartProduct> findCartProduct(String skuIds) {
        return productMapper.findCartProduct(skuIds);
    }

    @Override
    public void saveProduct(Product product) {
        if(product != null) {
            if(product.getId() == null) {
                productMapper.insertSelective(product);
            } else {
                productMapper.updateByPrimaryKey(product);
            }
        }
    }

    @Override
    public int getAuditProductCount(int companyId) {
        List<Integer> stateList = new ArrayList<>();
        stateList.add(0);   //待审核
        stateList.add(3);   //重新审核
        Product product = new Product();
        product.setRemoved(0);
        product.setCustomerId(companyId);
        Example example = new Example(Product.class);
        example.createCriteria().andEqualTo(product).andIn("state", stateList);
        return productMapper.selectCountByExample(example);
    }

    @Override
    public List<Map> searchMgrProduct(Map param) {
        return productMapper.searchMgrProduct(param);
    }

    @Override
    public int getMgrProductSkuCount(Map param) {
        return productMapper.getMgrProductSkuCount(param);
    }

    @Override
    public void updateProductPrice(int skuId, Double price, Double memberPrice, Double hotPrice, Double cenPrice) {
        if(price != null || memberPrice != null || hotPrice != null || cenPrice != null) {
            ProSku proSku = new ProSku();
            proSku.setId(skuId);
            proSku.setPrice(price);
            proSku.setMemberPrice(memberPrice);
            proSku.setHotPrice(hotPrice);
            proSku.setCenPrice(cenPrice);
            proSkuMapper.updateByPrimaryKeySelective(proSku);
        }
    }

    @Override
    public List<ProSku> findProSkuByProId(int productId) {
        ProSku sku = new ProSku();
        sku.setProductId(productId);
        sku.setRemoved(0);
        return proSkuMapper.select(sku);
    }

    @Override
    public List<ProSkuAttr> findSkuAttrBySkuId(int skuId) {
        ProSkuAttr skuAttr = new ProSkuAttr();
        skuAttr.setSkuId(skuId);
        return proSkuAttrMapper.select(skuAttr);
    }

    @Override
    public List<ProCategory> getProCategory(Integer customerId, Integer pcateid) {
        Integer level = getProductCategoryLevel(pcateid);
        if(level==null)level=0;
        if(level!=3){//三级类目无子类目时,取本层的,因为没有下一层了
            level++;//查的是下一级的类目与对应的数量
        }
        return productMapper.getProCategory(customerId,level,pcateid);
    }

    @Override
    public void removeProSku(int skuId) {
        ProSku proSku = new ProSku();
        proSku.setId(skuId);
        proSku.setRemoved(1);
        proSkuMapper.updateByPrimaryKeySelective(proSku);
    }

    @Override
    public void removeAllProSku(int productId) {
        ProSku proSku = new ProSku();
        proSku.setRemoved(1);
        Example example = new Example(ProSku.class);
        example.createCriteria().andEqualTo("productId", productId);
        proSkuMapper.updateByExampleSelective(proSku, example);
    }

    private Integer getProductCategoryLevel(Integer pcateid) {
        if(pcateid==null)return null;
        //先判断是几级类目
        Category category = proCategoryService.getCategorysById(pcateid);
        Integer level = null;
        if(category!=null){
            level = category.getCateType();
        }
        return level;
    }

    @Override
    public List<ProductExt> guessYouLike(int cateId) {
        ProSearchParam param = new ProSearchParam();
        param.setCategoryIds(cateId + "");
        param.setOrderType(6);      //浏览量倒序

        PageHelper.startPage(1, 15);
        return productMapper.getProductList(param, 3);
    }

    @Override
    public TPagination<ProductExt> getProductList(ProSearchParam param) {
        param.priceAI();
        String categoryIds = param.getCategoryIds();
        Integer categoryFirstId = null;
        if(StringUtils.isNotBlank(categoryIds)){
            categoryFirstId = Integer.valueOf(categoryIds.split(",")[0]);
        }
        Integer level = getProductCategoryLevel(categoryFirstId);//获取层级信息
        Page<Object> startPage = PageHelper.startPage(param.getPageNo(), param.getPageSize());
        List<ProductExt> productList = productMapper.getProductList(param,level);
        TPagination p = new TPagination(startPage, productList);
        return p;
    }

    @Override
    public ProSku getProSkuBySku(int productId, String sku, Integer removed) {
        ProSku proSku = new ProSku();
        proSku.setProductId(productId);
        proSku.setRemoved(removed);
        Example example = new Example(ProSku.class);
        Example.Criteria criteria = example.createCriteria();
        if(StrUtil.isNotBlank(sku)) {
            proSku.setSku(sku);
        } else {
            criteria.andIsNull("sku");
        }
        criteria.andEqualTo(proSku);
        List<ProSku> list = proSkuMapper.selectByExample(example);
        return CollectionUtil.isNotEmpty(list) ? list.get(0) : null;
    }

    @Override
    public void publishProduct(ProductData productData) throws BaseException {
        if(productData == null || CollectionUtil.isEmpty(productData.getSkuList())) {
            throw new BaseException("数据错误");
        }

        //todo 校验

        Product product = null;
        if(productData.getProductId() == null) {
            //新增商品
            product = new Product();
            product.setPubdate(new Date());
            product.setState(ProductStateEnum.INIT.getValue());     //新增商品的时候状态是待审核
            product.setIfSelf(productData.getIfSelf());
            product.setFirstPass(1);        //第一次审核
        } else {
            //更新商品
            product = productMapper.selectByPrimaryKey(productData.getProductId());
            product.setState(ProductStateEnum.RE.getValue());     //更新商品的时候状态是重新审核
        }
        if(product == null) {
            throw new BaseException("数据错误");
        }

        product.setCustomerId(productData.getCompanyId());
        product.setUserId(productData.getUserId());
        product.setName(productData.getProductName());
        product.setSubName(productData.getSubName());
        product.setCategoryFId(productData.getCategoryFId());
        product.setCategorySId(productData.getCategorySId());
        product.setCategoryTId(productData.getCategoryTId());
        product.setBrandId(productData.getBrandId());
        product.setModel(productData.getModel());
        product.setUnit(productData.getUnit());
        product.setIfPub(1);        //上架
        product.setPicPath(productData.getPicPath());
        product.setDescr(productData.getDescr());
        product.setServiceDuration(productData.getServiceDuration());
        product.setServiceUnit(productData.getServiceDuration() != null ? productData.getServiceUnit() : null);
        product.setService(productData.getService());
        if(!StrUtil.equals(productData.getAttachfile(), "#") && StrUtil.isNotBlank(productData.getAttachName())) {
            product.setAttachfile(productData.getAttachfile());
            product.setAttachName(productData.getAttachName());
        }
        product.setRemoved(0);
        this.saveProduct(product);

        //先删除所有的sku_attr和pro_sku
        if(productData.getProductId() != null) {
            ProSkuAttr proSkuAttr = new ProSkuAttr();
            proSkuAttr.setProductId(productData.getProductId());
            proSkuAttrMapper.delete(proSkuAttr);

            removeAllProSku(productData.getProductId());
        }

        for(ProductData.SkuData skuData : productData.getSkuList()) {
            List<ProductData.SkuData.SkuAttr> skuAttrList = skuData.getSkuAttrList();
            if(productData.getSkuList().size() > 1 && CollectionUtil.isEmpty(skuAttrList)) {
                throw new BaseException("数据错误");
            }
            if(!(skuData.getPrice() > 0 && skuData.getMemberPrice() > 0 && skuData.getPrice().doubleValue() >= skuData.getMemberPrice().doubleValue())) {
                throw new BaseException("价格设置错误");
            }

            ProSku proSku = null;
            if(productData.getProductId() != null) {
                //获取删除的pro_sku中有没有，有的话将其恢复，否则新增，防止每次更新保存的时候skuId都会改变
                proSku = getProSkuBySku(productData.getProductId(), skuData.getSkuAttrStr1(), null);
                if(proSku != null) {
                    proSku.setRemoved(0);
                    proSkuMapper.updateByPrimaryKeySelective(proSku);
                }
            }
            if(proSku == null) {
                proSku = new ProSku();
                proSku.setProductId(product.getId());
            }

            proSku.setSku(skuData.getSkuAttrStr1());
            proSku.setSkuStr(skuData.getSkuAttrStr2());
            proSku.setPrice(skuData.getPrice());
            proSku.setMemberPrice(skuData.getMemberPrice());
            if(proSku.getId() == null) {
                proSkuMapper.insertSelective(proSku);
            } else {
                proSkuMapper.updateByPrimaryKeySelective(proSku);
            }

            //库存
            //库存变动数量  skuData中的changeStock不是变动数量了，而是最终的数量了。
            int changeStock = skuData.getChangeStock() - (proSku.getStockQuantity() != null ? proSku.getStockQuantity() : 0);
            if(changeStock != 0) {

                ProductStock productStock = new ProductStock();
                productStock.setProductId(product.getId());
                productStock.setSkuId(proSku.getId());
                productStock.setUserid(productData.getUserId());
                productStock.setType(changeStock > 0 ? ProStockType.IN.getValue() : ProStockType.OUT.getValue());
                productStock.setQuantity(Math.abs(changeStock));
                productStock.setOperateType(changeStock > 0 ? ProStockOperateType.IN.getValue() : ProStockOperateType.OUT.getValue());
                productStockMapper.insertSelective(productStock);
            }

            for(ProductData.SkuData.SkuAttr skuAttr : skuData.getSkuAttrList()) {
                ProSkuAttr proSkuAttr = new ProSkuAttr();
                proSkuAttr.setProductId(product.getId());
                proSkuAttr.setSkuId(proSku.getId());
                proSkuAttr.setNameId(skuAttr.getNameId());
                proSkuAttr.setValueId(skuAttr.getValueId());
                proSkuAttr.setName(skuAttr.getName());
                proSkuAttr.setValue(skuAttr.getValue());
                proSkuAttrMapper.insertSelective(proSkuAttr);
            }
        }

        if(productData.getProductId() == null) {
            //新增商品的时候还需要插入pro_repository表
            ProRepository repository = new ProRepository();
            repository.setPid(productData.getCategoryTId());
            repository.setTitle(productData.getProductName());
            repository.setSecret(PasswordUtil.MD5_16(productData.getProductName()));
            proRepositoryMapper.insertSelective(repository);
        }

//        msgConfigService.sendMessage("EXAMINE_PERSON" , "AUDIT_PRODUCT" , null);//发送短信通知运营进行审核
        msgConfigService.sendMessage("AUDIT_PRODUCT" , null , null , new ArrayList());//发送短信通知运营进行审核
    }

    @Override
    public void upDownProduct(List<Integer> productIdList, boolean up) {
        if(CollectionUtil.isNotEmpty(productIdList)) {
            Product product = new Product();
            product.setIfPub(up ? 1 : 0);

            Example example = new Example(Product.class);
            example.createCriteria().andIn("id", productIdList);

            productMapper.updateByExampleSelective(product, example);
        }
    }

    @Override
    public void removeProduct(List<Integer> productIdList) {
        if(CollectionUtil.isNotEmpty(productIdList)) {
            Product product = new Product();
            product.setRemoved(1);

            Example example = new Example(Product.class);
            example.createCriteria().andIn("id", productIdList);

            productMapper.updateByExampleSelective(product, example);
        }
    }

    @Override
    public ProductExt getProductExtById(Integer productid) {
        return productMapper.getProductExtById(productid);
    }

    @Override
    public List<ProSkuExt> getProSkuExtByProductId(Integer productid) {
//        ProSku sku = new ProSku();
        List<ProSkuExt> skus = proSkuMapper.getProSkuExtByProductId(productid);
        return skus;
    }

    @Override
    public List<SkuModel> geteProModelByProductId(Integer porductid) {
        return proSkuMapper.geteProModelByProductId(porductid);
    }

    @Override
    public List<ProSku> getProSkuByProductId(Integer productid) {
        return proSkuMapper.getProSkusByProductId(productid);
    }

    @Override
    public ProSku getProSkuById(int skuId) {
        return proSkuMapper.selectByPrimaryKey(skuId);
    }

    @Override
    public List<CartListData> parseCartData(List<Map> cartList, boolean isSigned) {
        List<CartListData> cartListDataList = new ArrayList<>();

        if(CollectionUtil.isNotEmpty(cartList)) {
            StringBuilder skuIds = new StringBuilder();
            for(Map cart : cartList) {
                Integer skuId = Convert.toInt(cart.get("skuId"));
                Integer quantity = Convert.toInt(cart.get("quantity"));

                if(skuId != null && quantity != null) {
                    skuIds.append(skuId).append(",");
                }
            }

            if(skuIds.length() > 0) {
                skuIds = skuIds.deleteCharAt(skuIds.length() - 1);
                List<CartProduct> cartProductList = this.findCartProduct(skuIds.toString());
                if(CollectionUtil.isNotEmpty(cartProductList)) {
                    Set<Integer> companyIds = new HashSet<>();		//存放companyId，不重复
                    for(CartProduct cartProduct : cartProductList) {
                        if(cartProduct.getCompanyId() != null) {
                            companyIds.add(cartProduct.getCompanyId());
                        }
                    }

                    for(Integer companyId : companyIds) {
                        //是否是集采供应商
                        boolean isCenMember = memberService.getCenMember(companyId) != null;
                        CompanyExt comapnyExt = companyService.getCompanyExtByCustomerid(companyId);

                        List<CartProduct> cartProducts = new ArrayList<>();
                        for(CartProduct cartProduct : cartProductList) {
                            if(companyId.intValue() == cartProduct.getCompanyId().intValue()) {
                                for(Map cart : cartList) {
                                    if(cartProduct.getSkuId().intValue() == Convert.toInt(cart.get("skuId")).intValue()) {
                                        cartProduct.setQuantity(Convert.toInt(cart.get("quantity")));       //下单数量
                                        break;
                                    }
                                }
                                cartProduct.setRealPrice(calcProductPrice(isSigned, isCenMember, cartProduct.isHotProduct(),
                                        cartProduct.getMemberPrice(),  cartProduct.getHotPrice(), cartProduct.getCenPrice()));

                                //判断商品是否能购买
                                if(cartProduct.isCanBuy() && cartProduct.getStock().intValue() >= cartProduct.getQuantity().intValue()) {
                                    cartProduct.setCanBuy(true);
                                } else {
                                    cartProduct.setCanBuy(false);
                                }

                                cartProducts.add(cartProduct);
                            }
                        }
                        if(CollectionUtil.isNotEmpty(cartProducts)) {
                            CartListData cartListData = new CartListData();
                            cartListData.setCompanyId(companyId);
                            cartListData.setCompanyName(cartProducts.get(0).getCompanyName());
                            cartListData.setProductList(cartProducts);
                            cartListData.setCenMember(isCenMember);
                            cartListData.setQq(comapnyExt.getQq());
                            cartListDataList.add(cartListData);
                        }
                    }
                }
            }
        }
        return cartListDataList;
    }

    @Override
    public List<ProHotFloorExt> getHotProductFloor() {
        return proHotFloorMapper.getHotProductFloor();
    }

    @Override
    public List<ProShopFloorExt> getProShopFloor() {
        return proShopFloorMapper.getProShopFloor();
    }

    @Override
    public List<ProShopHotExt> getProShopHot() {
        return  proShopHotProductMapper.getProShopHot();
    }

	@Override
	public String getProductIdsByCompanyId(Integer companyId) {
		return productMapper.getProductIdsByCompanyId(companyId);
	}

    @Override
    public void addHitTimes(Integer productId) {
        productMapper.addHitTimes(productId);
    }

    @Override
    public List<Product> findProductWithCenSku(int companyId) {
        List<Product> list = new ArrayList<>();
        Product _product = new Product();
        _product.setCustomerId(companyId);
        _product.setIfPub(1);
        _product.setState(1);
        _product.setRemoved(0);
        Example example = new Example(Product.class);
        example.createCriteria().andEqualTo(_product);
        example.orderBy("id desc");
        List<Product> productList = productMapper.selectByExample(example);
        for(Product product : productList) {
            ProSku _proSku = new ProSku();
            _proSku.setRemoved(0);
            _proSku.setProductId(product.getId());
            Example _example = new Example(ProSku.class);
            _example.createCriteria().andEqualTo(_proSku).andGreaterThan("cenPrice", 0);
            List<ProSku> skuList = proSkuMapper.select(_proSku);
            if(CollectionUtil.isNotEmpty(skuList)) {
                List<ProSku> _skuList = new ArrayList<>();
                for(ProSku proSku : skuList) {
                    if(proSku.getCenPrice() != null && proSku.getCenPrice().doubleValue() > 0) {
                        _skuList.add(proSku);
                    }
                }
                if(CollectionUtil.isNotEmpty(_skuList)) {
                    product.setSkuList(_skuList);
                    list.add(product);
                }
            }
        }
        return list;
    }

    @Override
    public List<Product> listProductIdAndTime(int size) {
        return productMapper.selectBySize(size);
    }
}
